package cagt.tools.standard.poker;

import java.util.List;

import cagt.tools.LimitedHashSet;
import cagt.tools.standard.CardCollectionStats;
import cagt.tools.standard.FigureSequenceFinder;
import cagt.tools.standard.StandardCard;
import cagt.tools.standard.poker.holdem.Rules;

/**
 * Trick checker is a tool which controls if collection contains some poker
 * trick inside.
 * 
 * @author Konrad Sza�kowski
 * 
 */
public class TrickChecker {
	/*
	 * Subject.
	 */
	private LimitedHashSet<StandardCard> cards;
	private CardCollectionStats ccs;
	int lastCollectionHash;
	/*
	 * Results
	 */
	private Trick trick;

	public TrickChecker(LimitedHashSet<StandardCard> cards) {
		this.cards = cards;
		this.ccs = new CardCollectionStats(cards);
		if (this.cards.getLimit() != 5) {
			throw new IllegalArgumentException(
					"Set given to trick checker must be of size 5.");
		}
	}

	public LimitedHashSet<StandardCard> getCards() {
		return cards;
	}

	/**
	 * Returns tricks currently present in collection;
	 * 
	 * @return Tricks set.
	 */
	public Trick getTrick() {
		if (!cards.isFull()) {
			return null;
		}
		int collectionHash = cards.hashCode();
		if (trick == null || lastCollectionHash != collectionHash) {
			// Get the longest sequence
			List<StandardCard> longestSequence = FigureSequenceFinder
					.getLongestSequence(cards, Rules.holdemFiguresOrder);

			// Poker
			if (longestSequence.size() == 5
					&& ccs.getColorCooccurences().get(5) == 1) {
				trick = Trick.StraightFlush;
			} else
			// Four of kind
			if (ccs.getFigureCooccurences().get(4) == 1) {
				trick = Trick.FourOfAKind;
			} else
			// Full of house
			if (ccs.getFigureCooccurences().get(2) == 1
					&& ccs.getFigureCooccurences().get(3) == 1) {
				trick = Trick.FullOfHouse;
			} else
			// Flush
			if (ccs.getColorCooccurences().get(5) == 1) {
				trick = Trick.Flush;
			} else

			// Straight
			if (longestSequence.size() == 5) {
				trick = Trick.Straight;
			} else
			// Three of kind
			if (ccs.getFigureCooccurences().get(3) == 1) {
				trick = Trick.ThreeOfKind;
			} else
			// Two pairs
			if (ccs.getFigureCooccurences().get(2) == 2) {
				trick = Trick.TwoPairs;

			} else
			// Pair
			if (ccs.getFigureCooccurences().get(2) == 1) {
				trick = Trick.Pair;
			}
			// No tricks
			else {
				trick = Trick.NoTrick;
			}
			// Hash copy
			lastCollectionHash = collectionHash;
		}
		return trick;
	}
}
